/*
 * File Name:               XContainer.cs
 *
 * Description:             组件模式的容器类
 *                          todo 组件之间的通信过程
 * Author:                  lisiyu
 * Create Date:             2016/09/28
 */

using System;
using System.Collections.Generic;

public class XContainer<TOwner, TComponent, TContainer> 
    where TOwner : class
    where TComponent : IComponent<TOwner, TComponent, TContainer>
    where TContainer : XContainer<TOwner, TComponent, TContainer>, new()
{
    protected TOwner mOwner;
    protected Dictionary<Type, TComponent> mComponents;

    public static TContainer create(TOwner owner)
    {
        TContainer ret = new TContainer();
        ret.mOwner = owner;
        ret.mComponents = new Dictionary<Type, TComponent>();

        return ret;
    }

    public void onRecycle()
    {
        foreach (var tmp in mComponents)
        {
            tmp.Value.onRemove();
            tmp.Value.onRecycle();
        }
        mComponents.Clear();
        mComponents = null;
        mOwner = null;
    }

    public K addComponent<K>(params object[] args) where K : TComponent, new()
    {
        K ret = null;
        var key = typeof(K);
        if (mComponents.ContainsKey(key))
        {
            ret = mComponents[key] as K;
        }
        else
        {
            ret = new K();
            (ret as TComponent).onSpawn(mOwner, this as TContainer);
            (ret as TComponent).onAdd(args);
            mComponents.Add(key, ret);
        }
        return ret;
    }

    public void removeComponent<K>() where K : TComponent
    {
        var key = typeof(K);
        if (mComponents.ContainsKey(key))
        {
            mComponents[key].onRemove();
            mComponents[key].onRecycle();
            mComponents.Remove(key);
        }
    }

    public K getComponent<K>() where K : TComponent
    {
        var key = typeof(K);
        if (mComponents.ContainsKey(key))
            return mComponents[key] as K;
        return null;
    }
}